namespace SubhadraSolutions.Sharp.Logging.LogSubscribers
{
    using SubhadraSolutions.Sharp.Logging.Contracts;
    using SubhadraSolutions.Sharp.Utils;
    using System.Collections.Generic;

    public abstract class AbstractLogSubscriber : AbstractInitializableAndDisposable, ILogSubscriber
    {
        #region Fields

        private readonly object _syncLock = new object();

        private ILogPublisher _logPublisher;

        #endregion Fields

        #region Constructors

        protected AbstractLogSubscriber()
        {
            IsDebugEnabled = true;
            IsErrorEnabled = true;
            IsFatalEnabled = true;
            IsInfoEnabled = true;
            IsWarnEnabled = true;
            EnabledCategories = LogItemCategories.Technical | LogItemCategories.Functional;
        }

        #endregion Constructors

        #region Properties

        public bool IsDebugEnabled
        {
            get;
            set;
        }

        public bool IsErrorEnabled
        {
            get;
            set;
        }

        public bool IsFatalEnabled
        {
            get;
            set;
        }

        public bool IsInfoEnabled
        {
            get;
            set;
        }

        public bool IsWarnEnabled
        {
            get;
            set;
        }

        public string LogPublisherName
        {
            get;
            set;
        }

        public LogItemCategories EnabledCategories
        {
            get;
            set;
        }

        #endregion Properties

        #region Methods

        protected override void initializeProtected()
        {
            if (_logPublisher == null)
            {
                _logPublisher = getLogPublisher();
            }
            _logPublisher.OnFlush += _logPublisher_OnFlush;
            //initializeProtected();
        }

        protected override void Dispose(bool disposing)
        {
            if (_logPublisher != null)
            {
                _logPublisher.OnFlush -= _logPublisher_OnFlush;
            }
        }

        protected virtual ILogPublisher getLogPublisher()
        {
            return LoggerLogPublisherFactory.Instance.GetLogPublisher(LogPublisherName);
        }

        protected abstract void publishLogs(IEnumerable<LogStoreItem> e);

        private void _logPublisher_OnFlush(object sender, IEnumerable<LogStoreItem> e)
        {
            IEnumerable<LogStoreItem> items = e;
            if (
                !(IsDebugEnabled && IsErrorEnabled && IsFatalEnabled && IsInfoEnabled && IsWarnEnabled))
            {
                items = LogItemFilterHelper.Filter(e, this);
            }
            publishLogs(items);
        }

        #endregion Methods
    }
}